import cameras
import svc
import service
import log
import blue
import uthread
import sys
MOUSE_LOOK_SPEED = 0.005

class EveCameraClient(svc.cameraClient):
    __guid__ = 'svc.eveCameraClient'
    __replaceservice__ = 'cameraClient'
    __dependencies__ = svc.cameraClient.__dependencies__
    __dependencies__.extend(['mouseInput'])
    __notifyevents__ = svc.cameraClient.__notifyevents__
    __notifyevents__.extend(['OnEntityCreated', 'OnEntityDeleted'])

    def Run(self, *etc):
        svc.cameraClient.Run(self, *etc)
        defaultCamera = cameras.PolarCamera()
        self.sharedCameras = {'Default Polar Camera': defaultCamera}
        self.cameraStack = [defaultCamera]
        self.stop = False
        self.entityLoop = None
        self.mouseInput.RegisterCallback(const.INPUT_TYPE_MOUSEDOWN, self.OnMouseDown)
        self.mouseInput.RegisterCallback(const.INPUT_TYPE_MOUSEUP, self.OnMouseUp)
        self.mouseInput.RegisterCallback(const.INPUT_TYPE_MOUSEMOVE, self.OnMouseMove)
        self.mouseInput.RegisterCallback(const.INPUT_TYPE_MOUSEWHEEL, self.OnMouseWheel)



    def Stop(self, stream):
        self.mouseInput.UnRegisterCallback(const.INPUT_TYPE_MOUSEDOWN, self.OnMouseDown)
        self.mouseInput.UnRegisterCallback(const.INPUT_TYPE_MOUSEUP, self.OnMouseUp)
        self.mouseInput.UnRegisterCallback(const.INPUT_TYPE_MOUSEMOVE, self.OnMouseMove)
        self.mouseInput.UnRegisterCallback(const.INPUT_TYPE_MOUSEWHEEL, self.OnMouseWheel)



    def OnMouseDown(self, button, posX, posY, entityID):
        activeCamera = self.GetActiveCamera()
        activeCamera.OnMouseDown(button)



    def OnMouseUp(self, button, posX, posY, entityID):
        activeCamera = self.GetActiveCamera()
        activeCamera.OnMouseUp(button)



    def OnMouseMove(self, deltaX, deltaY, entityID):
        activeCamera = self.GetActiveCamera()
        activeCamera.OnMouseMove((deltaX * MOUSE_LOOK_SPEED), (deltaY * MOUSE_LOOK_SPEED))



    def OnMouseWheel(self, delta):
        activeCamera = self.GetActiveCamera()
        activeCamera.AdjustZoom((delta * MOUSE_LOOK_SPEED))



    def OnEntityCreated(self, entityID):
        if (entityID == session.charid):
            self.OnAvatarEnterWorldspace(entityID)
            self.StartCamera()



    def OnEntityDeleted(self, entityID, sceneID):
        if (entityID == session.charid):
            self.StopCamera()



    def StartCamera(self):
        self.entityLoop = uthread.new(self.CameraLoop).context = 'CameraClient::CameraLoop'
        self.stop = False



    def StopCamera(self):
        self.stop = True



    def OnAvatarEnterWorldspace(self, playerEntID):
        if (len(self.cameraStack) > 1):
            self.cameraStack = [self.cameraStack[0]]
        gameCamera = cameras.IncarnaCamera()
        gameCamera.AddBehavior(cameras.CharacterOffsetBehaviour(playerEntID), priority=1)
        self.AddSharedCamera('Player Camera', gameCamera, setActive=True)



    def _CreateCameraRenderJob(self):
        if not self.renderJobCreated:
            sceneManager = sm.GetService('sceneManager')
            sceneManager.view = self.GetActiveCamera().viewMatrix
            sceneManager.CreateJob()
            self.renderJobCreated = True



    def CameraLoop(self):
        while ((self.state != service.SERVICE_STOPPED) and (not self.stop)):
            try:
                activeCam = self.GetActiveCamera()
                activeCam.UpdateProjectionMatrix()
                activeCam.Update()
            except Exception:
                log.LogException('Error in CameraLoop')
                sys.exc_clear()
            blue.pyos.synchro.Sleep(5)





